Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1231 onboarding numeraire selection2 #28

Merged
merged 19 commits into from
Jun 14, 2024

Conversation

Valentine1898
Copy link
Contributor

@Valentine1898 Valentine1898 commented Jun 13, 2024

close penumbra-zone/web#1231
close penumbra-zone/web#1063

  • the user may not select any numeraire, it won't break anything
  • all old prices are deleted, no matter how numeraires changed (this can be improved later)
image image

Copy link

changeset-bot bot commented Jun 13, 2024

⚠️ No Changeset found

Latest commit: d2f7230

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines 35 to 38
const { chainId } = useChainIdQuery();
const { selectedNumeraires, selectNumeraire, saveNumeraires, networkChainId } =
useStore(useNumerairesSelector);
const numeraires = useMemo(() => getNumeraireFromRegistry(chainId ?? networkChainId), [chainId]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason we can't get chainId for onboarding using useChainIdQuery (even though the services are already started).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, could you add a comment explaining this, for future devs' sake?

Comment on lines +125 to +136
if (changes['params']) {
const stored = changes['params'].newValue as
| StorageItem<LocalStorageState['params']>
| undefined;
set(
produce((state: AllSlices) => {
state.network.chainId = stored?.value
? AppParameters.fromJsonString(stored.value).chainId
: state.network.chainId;
}),
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to point out that we never actually save 'params', seems like that should be a separate issue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, where is params coming from? Unless I'm missing something, I don't think changes will ever have a params key 🤔

Also, we don't store the chain ID in local storage. We store the grpcEndpoint, from which we fetch the chain ID on app startup. So I think this if (changes['params']) block should be deleted.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now that the chain ID is fetched from local storage in startWalletServices. But to your point, it seems to never be saved to local storage. So yeah, maybe we should just remove all references to it in local storage? 🤔

Copy link
Contributor Author

@Valentine1898 Valentine1898 Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the params were added to local storage as part of a PR to solve the problem of running service work without a network (probably #998)
I accept that it was intended that the params should be stored, but it was just missed by mistake

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@turbocrime perhaps you can give more context regarding params

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created a separate issue for that #32

@@ -22,5 +23,6 @@ export interface LocalStorageState {
passwordKeyPrint: KeyPrintJson | undefined;
fullSyncHeight: number | undefined;
knownSites: OriginRecord[];
params: Jsonified<AppParameters> | undefined;
params: Stringified<AppParameters> | undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't seem to save Jsonified to local storage

Comment on lines 95 to 101
case ServicesMessage.ChangeNumeraires:
void (async () => {
const newNumeraires = await localExtStorage.get('numeraires');
blockProcessor.setNumeraires(newNumeraires.map(n => AssetId.fromJsonString(n)));
await indexedDb.clearSwapBasedPrices();
})().then(() => respond());
return true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured we might not have to stop sync to change the numeraires

numeraires: Metadata[];
numeraires: AssetId[];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't actually need Metadata here

Comment on lines +671 to +684
async clearSwapBasedPrices(): Promise<void> {
const tx = this.db.transaction('PRICES', 'readwrite');
const store = tx.objectStore('PRICES');

let cursor = await store.openCursor();
while (cursor) {
const price = EstimatedPrice.fromJson(cursor.value);
if (!price.numeraire?.equals(this.stakingTokenAssetId)) {
await cursor.delete();
}
cursor = await cursor.continue();
}
await tx.done;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be much easier to delete all price records, but we should actually keep the prices for delegation assets because they don't depend on the numeraires setting

@grod220 grod220 requested review from a team and removed request for grod220 June 13, 2024 15:23
Copy link
Contributor

@jessepinho jessepinho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work. I have a few smaller comments, but the biggest issue is whether there's a way to repopulate the price data after wiping it out because the numeraires changed. If that's already addressed and I'm missing something, feel free to merge after addressing my comments. Otherwise, I think that needs addressing before merge.

apps/extension/src/routes/popup/settings/settings.tsx Outdated Show resolved Hide resolved
apps/extension/src/shared/components/numeraires-form.tsx Outdated Show resolved Hide resolved
Comment on lines 35 to 38
const { chainId } = useChainIdQuery();
const { selectedNumeraires, selectNumeraire, saveNumeraires, networkChainId } =
useStore(useNumerairesSelector);
const numeraires = useMemo(() => getNumeraireFromRegistry(chainId ?? networkChainId), [chainId]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, could you add a comment explaining this, for future devs' sake?

apps/extension/src/shared/components/numeraires-form.tsx Outdated Show resolved Hide resolved
Comment on lines +125 to +136
if (changes['params']) {
const stored = changes['params'].newValue as
| StorageItem<LocalStorageState['params']>
| undefined;
set(
produce((state: AllSlices) => {
state.network.chainId = stored?.value
? AppParameters.fromJsonString(stored.value).chainId
: state.network.chainId;
}),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, where is params coming from? Unless I'm missing something, I don't think changes will ever have a params key 🤔

Also, we don't store the chain ID in local storage. We store the grpcEndpoint, from which we fetch the chain ID on app startup. So I think this if (changes['params']) block should be deleted.

Comment on lines +125 to +136
if (changes['params']) {
const stored = changes['params'].newValue as
| StorageItem<LocalStorageState['params']>
| undefined;
set(
produce((state: AllSlices) => {
state.network.chainId = stored?.value
? AppParameters.fromJsonString(stored.value).chainId
: state.network.chainId;
}),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now that the chain ID is fetched from local storage in startWalletServices. But to your point, it seems to never be saved to local storage. So yeah, maybe we should just remove all references to it in local storage? 🤔

Comment on lines +119 to +121
setNumeraires(numeraires: AssetId[]): void {
this.numeraires = numeraires;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something I'm a little unclear on: when wallet services calls this method, it will wipe out existing prices. But how do those prices get repopulated? Does the user have to wait for the next swap to appear on chain to trigger re-saving of prices? Or is there a way to ensure the prices get updated as soon as the numeraire gets updated? (Sorry if I'm missing something that's already addressed in your code.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if swaps are frequent, it would be a minor inconvenience to the user that they wouldn't see equivalent prices for a while after changing numeraires.

Other solutions are to:

  • scan through the whole list of numeraires regardless of the user's choice (then the user's choice will only affect the service layer that returns prices) - but this is an additional cost in scanning and storage.

  • after changing numeraires, scan some number of blocks into the past - theoretically, we can add this improvement in the future

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah — if you and Henry already discussed it and he's fine with it, then it's fine. This is probably more of a product decision than an engineering one.

@Valentine1898
Copy link
Contributor Author

but the biggest issue is whether there's a way to repopulate the price data after wiping it out because the numeraires changed

@jessepinho
That's a good point, I'll add some comments to the code explaining this.

It's a bit of a controversial decision as far as I'm concerned, but the user will just have to wait a bit for the prices to populate "naturally" by scanning for new blocks and BSODs in them.

Also the comment where Henry and I discussed this

penumbra-zone/web#1063 (comment)

@Valentine1898
Copy link
Contributor Author

Since this PR contains both packages and extension changes, I will also make a duplicate PR in the penumbra-zone/web repo that will only contain the packages changes

@Valentine1898 Valentine1898 merged commit 27d8552 into main Jun 14, 2024
6 checks passed
@Valentine1898 Valentine1898 deleted the 1231-onboarding-numeraire-selection2 branch June 14, 2024 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Onboarding numeraire selection configurable numeraire token
2 participants